package com.wunong.smart.commission.starter.repository;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.wunong.smart.commission.client.query.CommissionQueryDTO;
import com.wunong.smart.commission.starter.converter.CommissionConverter;
import com.wunong.smart.commission.domain.model.CommissionDomain;
import com.wunong.smart.commission.domain.repository.CommissionRepository;
import com.wunong.smart.commission.starter.infrastructure.mapper.CommissionMapper;
import com.wunong.smart.commission.starter.infrastructure.po.CommissionPO;
import com.wunong.smart.domain.platform.common.BizSource;
import com.wunong.smart.domain.platform.enums.CommonErrorEnum;
import com.wunong.smart.domain.platform.exception.DAOException;
import com.wunong.smart.domain.platform.utils.TimeUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

/**
 * @author create by zealot.zt
 */
public class CommissionRepositoryImpl implements CommissionRepository {

    @Resource
    protected CommissionMapper commissionMapper;

    @Override
    public Long save(CommissionDomain domain) {
        LocalDateTime now = TimeUtils.nowWithoutMs();
        domain.setGmtCreate(now);
        domain.setGmtModified(now);

        CommissionPO po = toPo(domain);
        commissionMapper.insert(po);

        domain.setId(po.getId());
        return po.getId();
    }

    @Override
    public void update(CommissionDomain domain) {
        domain.setGmtModified(TimeUtils.nowWithoutMs());
        CommissionPO po = toPo(domain);

        Wrapper<CommissionPO> wrapper = Wrappers.lambdaQuery(CommissionPO.class)
                .eq(CommissionPO::getUserId, domain.getUserId())
                .eq(CommissionPO::getId, domain.getId());

        if (commissionMapper.update(po, wrapper) <= 0) {
            throw new DAOException(CommonErrorEnum.CONCURRENT_UPDATE_ENTITY_ERROR);
        }
    }

    @Override
    public CommissionDomain getById(Long id) {
        Wrapper<CommissionPO> wrapper = Wrappers.lambdaQuery(CommissionPO.class)
                .eq(CommissionPO::getId, id);

        return toDomain(commissionMapper.selectOne(wrapper));
    }

    @Override
    public List<CommissionDomain> queryByIds(Collection<Long> ids) {
        return toDomain(commissionMapper.selectBatchIds(ids));
    }

    @Override
    public CommissionDomain getById(Long userId, Long id) {
        Wrapper<CommissionPO> wrapper = Wrappers.lambdaQuery(CommissionPO.class)
                .eq(CommissionPO::getUserId, userId)
                .eq(CommissionPO::getId, id);

        return toDomain(commissionMapper.selectOne(wrapper));
    }

    @Override
    public List<CommissionDomain> queryByBiz(String bizId, Integer bizType, Integer commissionType) {
        Wrapper<CommissionPO> wrapper = Wrappers.lambdaQuery(CommissionPO.class)
                .eq(CommissionPO::getBizId, bizId)
                .eq(CommissionPO::getBizType, bizType)
                .eq(CommissionPO::getCommissionType, commissionType)
                .orderByDesc(CommissionPO::getGmtCreate);

        return toDomain(commissionMapper.selectList(wrapper));
    }

    @Override
    public CommissionDomain getByBiz(BizSource source, String commissionType) {
        Wrapper<CommissionPO> wrapper = Wrappers.lambdaQuery(CommissionPO.class)
                .eq(CommissionPO::getBizId, source.getBizId())
                .eq(CommissionPO::getBizType, source.getBizType())
                .eq(CommissionPO::getCommissionType, commissionType);

        return toDomain(commissionMapper.selectFirst(wrapper));
    }

    @Override
    public List<CommissionDomain> query(CommissionQueryDTO queryDTO) {
        LambdaQueryWrapper<CommissionPO> wrapper = Wrappers.lambdaQuery(CommissionPO.class)
                .orderByDesc(CommissionPO::getGmtCreate);

        if (Objects.nonNull(queryDTO.getId())) {
            wrapper.eq(CommissionPO::getId, queryDTO.getId());
        }

        // 业务编号
        if (Objects.nonNull(queryDTO.getBizId())) {
            wrapper.eq(CommissionPO::getBizId, queryDTO.getBizId());
        }

        // 业务类型
        if (Objects.nonNull(queryDTO.getBizType())) {
            wrapper.eq(CommissionPO::getBizType, queryDTO.getBizType());
        }

        // 用户编号
        if (Objects.nonNull(queryDTO.getUserId())) {
            wrapper.eq(CommissionPO::getUserId, queryDTO.getUserId());
        }

        // 用户角色
        if (Objects.nonNull(queryDTO.getUserRole())) {
            wrapper.eq(CommissionPO::getUserRole, queryDTO.getUserRole());
        }

        // 类型
        if (Objects.nonNull(queryDTO.getCommissionType())) {
            wrapper.eq(CommissionPO::getCommissionType, queryDTO.getCommissionType());
        }

        // 代办状态
        if (Objects.nonNull(queryDTO.getStatuses())) {
            wrapper.in(CommissionPO::getStatus, queryDTO.getStatuses());
        }

        return toDomain(commissionMapper.selectList(wrapper));
    }

    protected List<CommissionDomain> toDomain(List<CommissionPO> pos) {
        return CommissionConverter.toDomain(pos);
    }

    protected CommissionDomain toDomain(CommissionPO po) {
        return CommissionConverter.toDomain(po);
    }

    protected CommissionPO toPo(CommissionDomain domain) {
        return CommissionConverter.toPo(domain);
    }

}
